package com.symaster.common.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author yinmiao
 * @version 2022-04-09 14:25
 */
public class HttpEntity {

    private static final Logger logger = LoggerFactory.getLogger(HttpEntity.class);
    private final Map<String, String> commonHead = new HashMap<>();
    private URL url;

    public HttpEntity(URL url) {
        this.url = url;
    }

    public HttpEntity(String url) {
        try {
            this.url = new URL(url);
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("URL 格式错误");
        }
    }

    public URL getUrl() {
        return url;
    }

    public void setUrl(URL url) {
        this.url = url;
    }

    public void headPut(String key, String value) {
        commonHead.put(key, value);
    }

    public void headRemove(String key) {
        commonHead.remove(key);
    }

    public String sendPostNotReload(String uri, String body) {
        try {
            return _sendPost(uri, body);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(String.format("服务器链接失败: %s", e.getMessage()));
        }
    }

    public <T> List<T> sendPostOfArray(String uri, String body, Class<T> clazz) {
        String s = sendPost(uri, body);
        if (StringUtils.isEmpty(s)) {
            return null;
        }
        return JSONObject.parseArray(s, clazz);
    }

    public <T> T sendPost(String uri, String body, Class<T> clazz) {
        String s = sendPost(uri, body);
        if (StringUtils.isEmpty(s)) {
            return null;
        }
        return JSONObject.parseObject(s, clazz);
    }

    public String sendPost(String uri, String body) {
        Exception error = null;
        for (int i = 0; i < 3; i++) {
            try {
                return _sendPost(uri, body);
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                e.printStackTrace();
                error = e;
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (Exception ignored) {
                }
            }
        }
        throw new RuntimeException(String.format("服务器链接失败: %s", error.getMessage()));
    }

    public String sendPost(String uri) {
        return sendPost(uri, null);
    }

    public <T> T sendGet(String uri, Class<T> clazz) {
        String s = sendGet(uri);
        if (StringUtils.isEmpty(s)) {
            return null;
        }
        return JSONObject.parseObject(s, clazz);
    }

    public String sendGet(String uri) {
        try {
            return _sendGet(uri);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public <T> List<T> sendGetOfArray(String uri, Class<T> clazz) {

        String s = sendGet(uri);
        if (StringUtils.isEmpty(s)) {
            return null;
        }
        return JSONObject.parseArray(s, clazz);
    }

    private String _sendPost(String uri, String body) throws Exception {
        if (!uri.startsWith("/")) {
            uri = "/" + uri;
        }
        HttpPost httpPost = new HttpPost(getServerHost() + uri);
        if (commonHead.size() > 0) {
            addHeadToHttpRequestBase(httpPost);
        }
        if (StringUtils.isNotEmpty(body)) {
            httpPost.setEntity(new StringEntity(body, StandardCharsets.UTF_8));
        }
        String resultDataStr = CommonUtil.getResultDataStr(CommonUtil.executeRequest(httpPost, StandardCharsets.UTF_8), "200");
        logger.debug("sendPost uri:{}, params:{}, result:{}", uri, body, resultDataStr);
        return resultDataStr;
    }

    private String _sendGet(String uri) throws Exception {
        if (!uri.startsWith("/")) {
            uri = "/" + uri;
        }
        HttpGet httpGet = new HttpGet(getServerHost() + uri);
        if (commonHead.size() > 0) {
            addHeadToHttpRequestBase(httpGet);
        }
        String resultDataStr = CommonUtil.getResultDataStr(CommonUtil.executeRequest(httpGet, StandardCharsets.UTF_8), "200");
        logger.debug("sendPost uri:{}, result:{}", uri, resultDataStr);
        return resultDataStr;
    }

    private String getServerHost() {
        if (url.getPort() <= 0) {
            return String.format("%s://%s%s", url.getProtocol(), url.getHost(), url.getPath());
        } else {
            return String.format("%s://%s:%s%s", url.getProtocol(), url.getHost(), url.getPort(), url.getPath());
        }
    }

    private void addHeadToHttpRequestBase(HttpRequestBase base) {
        for (String key : commonHead.keySet()) {
            String value = commonHead.get(key);
            base.addHeader(key, value);
        }
    }
}
